/*
 * @Author: zhanwei xu
 * @Date: 2023-11-30 14:37:50
 * @LastEditors: zhanwei xu
 * @LastEditTime: 2024-02-22 17:42:01
 * @Description:
 *
 * Copyright (c) 2023 by zhanwei xu, Tsinghua University, All Rights Reserved.
 */
import { BaseServices } from "./base.services";
import { RoleEnum } from "@/models/@types";
import { Method, RespInfo, Uri, config } from "./config";
import { Message } from "@arco-design/web-vue";

export type GeneratePromptReq = {
  role: RoleEnum;
  content: string;
};

export class CommonService extends BaseServices {
  private static _ins: CommonService = new CommonService();
  public static get ins(): CommonService {
    return this._ins ? this._ins : (this._ins = new CommonService());
  }

  /** 文本转语音 */
  public tts(txt: string, end: (data: ArrayBuffer) => void, error: (e) => void): void {
    const url = "https://www.cwjiaoyu.cn/tts_file_paddle_mix";
    const data = { txt };
    fetch(url, { method: "POST", headers: { Accept: "*/*", "Content-Type": "application/json" }, body: JSON.stringify({ ...data }) })
      .then((response) => response.arrayBuffer())
      .then((arrayBuffer) => {
        end(arrayBuffer);
      })
      .catch((err) => error(err));
  }

  /** 文本转语音 */
  public ttsV2(txt: string, audio: HTMLAudioElement, mediaSource: MediaSource, stop: (callback: Function) => void): void {
    // const url = "https://www.cwjiaoyu.cn/tts_file_paddle_mix";
    const url = "https://bak.zaiwenai.top/tts_stream_openai_mix";
    const data = { txt, speaker: "shimmer" }; // alloy,echo,shimmer

    let isDone = false; // 是否传输结束
    let isReady = true; // 是否准备好下一次加载
    let bufferList = []; // 缓冲区数组

    // 设置audio元素的src为MediaSource对象的URL
    audio.src = URL.createObjectURL(mediaSource);
    audio.play();
    // 当MediaSource对象打开时发出sourceopen事件
    mediaSource.addEventListener("sourceopen", function () {
      const controller = new AbortController();
      const signal = controller.signal;
      // 创建一个MediaSource对象的sourceBuffer
      let sourceBuffer = mediaSource.addSourceBuffer("audio/mpeg"); // 请根据实际音频格式修改
      stop(function () {
        // 传输结束，关闭
        controller.abort();
        mediaSource.removeEventListener("sourceopen", () => {
          console.log("mediaSource.removeEventListener:sourceopen");
        });
      });
      // 传输完毕事件监听器
      sourceBuffer.addEventListener("updateend", () => {
        if (bufferList.length !== 0) {
          // 读取完毕后缓冲区有数据，从缓冲区读取
          sourceBuffer.appendBuffer(bufferList.shift());
        } else {
          // 缓冲区无数据
          if (isDone) {
            // 传输结束，关闭
            sourceBuffer.abort();
            mediaSource.endOfStream();
          } else {
            isReady = true; // 准备好进行下一次传输
          }
        }
      });
      fetch(url, { method: "POST", headers: { "Content-Type": "audio/mpeg" }, body: JSON.stringify({ ...data }), signal })
        .then((response) => {
          // 创建 ReadableStream
          const reader = response.body.getReader();
          // 声明处理函数
          const processRead = async (params) => {
            const { done, value } = params;
            if (!done) {
              if (isReady) {
                // 如果已准备好则直接读取
                sourceBuffer.appendBuffer(value);
                isReady = false;
              } else {
                // 否则加入缓冲区
                bufferList = [...bufferList, value];
              }
              // 读取完毕后递归进行下一次读取
              await reader.read().then(processRead);
            } else {
              console.log("可读流读取完毕");
              // 关闭流式传输
              sourceBuffer.abort();
              mediaSource.endOfStream();
            }
          };
          // 开始读取
          reader.read().then(processRead);
        })
        .catch(function (err) {
          // 处理错误
          console.error("获取音频数据失败：", err);
        });
    });
  }

  /** 语音转文本 */
  public vtt(file: File, end: (data: string) => void, error: (e) => void): void {
    const url = "https://ai.zaiwen.org.cn/whisper";
    const data = new FormData();
    data.append("file", file);
    fetch(url, { method: "POST", body: data })
      .then((response) => response.json())
      .then((res) => end(res.text))
      .catch((err) => error(err));
  }

  public sts(file: File, speaker: string, end: (data) => void, error: (e) => void): void {
    const url = "https://ai.zaiwen.org.cn/vtt?speaker=" + speaker;
    const data = new FormData();
    data.append("file", file);

    let isDone = false; // 是否传输结束
    let isReady = true; // 是否准备好下一次加载
    let bufferList = []; // 缓冲区数组
    const mediaSource = new MediaSource();
    const audio = new Audio();

    // 设置audio元素的src为MediaSource对象的URL
    audio.src = URL.createObjectURL(mediaSource);
    audio.play();
    // 当MediaSource对象打开时发出sourceopen事件
    mediaSource.addEventListener("sourceopen", function () {
      const controller = new AbortController();
      const signal = controller.signal;
      // 创建一个MediaSource对象的sourceBuffer
      let sourceBuffer = mediaSource.addSourceBuffer("audio/mpeg"); // 请根据实际音频格式修改
      // stop(function () {
      //   // 传输结束，关闭
      //   controller.abort();
      //   mediaSource.removeEventListener("sourceopen", () => {
      //     console.log("mediaSource.removeEventListener:sourceopen");
      //   });
      // });
      // 传输完毕事件监听器
      sourceBuffer.addEventListener("updateend", () => {
        if (bufferList.length !== 0) {
          // 读取完毕后缓冲区有数据，从缓冲区读取
          sourceBuffer.appendBuffer(bufferList.shift());
        } else {
          // 缓冲区无数据
          if (isDone) {
            // 传输结束，关闭
            sourceBuffer.abort();
            mediaSource.endOfStream();
          } else {
            isReady = true; // 准备好进行下一次传输
          }
        }
      });
      fetch(url, { method: "POST", body: data, redirect: "follow" })
        .then((response) => {
          console.log(response);
          // 创建 ReadableStream
          const reader = response.body.getReader();
          // 声明处理函数
          const processRead = async (params) => {
            const { done, value } = params;
            if (!done) {
              if (isReady) {
                // 如果已准备好则直接读取
                sourceBuffer.appendBuffer(value);
                isReady = false;
              } else {
                // 否则加入缓冲区
                bufferList = [...bufferList, value];
              }
              // 读取完毕后递归进行下一次读取
              await reader.read().then(processRead);
            } else {
              console.log("可读流读取完毕");
              // 关闭流式传输
              sourceBuffer.abort();
              mediaSource.endOfStream();
              //  获取语音时长
              end({ blob: mediaSource, duration: audio.duration });
            }
          };
          // 开始读取
          reader.read().then(processRead);
          return response.json();
        })
        .catch((err) => error(err));
    });
  }

  /** 下发验证码 */
  public send(phone: string): Promise<void> {
    const url = config.usersbeasking + Uri.Common_Sms + Method.Send;
    const data = { phone };
    return new Promise((resolve, reject) => {
      if (!phone || !/^1[3456789]\d{9}$/.test(phone)) {
        Message.error("请先正确输入手机号码");
        reject();
        return;
      }
      return this.request(url, data)
        .then(() => {
          Message.success("短信发送成功");
          resolve();
        })
        .catch((err) => {
          Message.error("短信发送失败,请再试一次吧");
          reject(err);
        });
    });
  }

  /** 验证短信验证码 */
  public verify(phone: string, code: string): Promise<string> {
    const url = config.usersbeasking + Uri.Common_Sms + Method.Verify;
    const data = { code, phone };
    return new Promise((resolve) => {
      if (phone && code) {
        return this.request(url, data).then((res: RespInfo) => {
          resolve(res.code);
        });
      } else {
        Message.error("请先输入手机号码或验证码");
        resolve("");
      }
    });
  }
}

export const commonService: CommonService = CommonService.ins;
